#pragma once
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#include "Log.hpp"
#include "Error.hpp"

using std::cout;
using std::endl;

class Util
{
public:
    // 将文件设置为非阻塞
    static void SetNonBlock(int fd)
    {
        int old = fcntl(fd,F_GETFL);
        int n = fcntl(fd,F_SETFL, old | O_NONBLOCK);
        if( n < 0)
        {
            LOG(ERROR,"SetNonBlock fail..");
        }
    }
    // 将进程守护进程化：
    // 1.setsid
    // 2.调用setsid不能以进程组长的身份运行
    // 3.屏蔽一些异常信号
    // 4.文件描述符的处理
    // 5.更改路径 - 可选
    static void Daemon()
    {
        // 创建子进程,让进程执行服务器的代码,父进程终止
        // 1.不能以进程组组长的身份运行
        int pid = fork();
        if(pid > 0) // 父进程
            exit(0);
        
        // 2.setsid
        pid_t p = setsid();
        if(p < 0)
        {
            printf("Daemon::setsid failed %d-%s\n",errno,strerror(errno));
        }
        // 3.更改进程的路径
        // chdir("/"); // 不能更改路径，改了就不对了
        // 守护进程是孤儿进程 -- 子进程
        // 守护进程化
        // 3.忽略信号
        signal(SIGPIPE,SIG_IGN);
        signal(SIGCHLD,SIG_IGN);
        // 4.关闭0,1,2文件描述符
        int fd = open("/dev/null",O_RDWR);
        if(fd < 0)
        {
            printf("Daemon::open failed %d-%s\n",errno,strerror(errno));
        }
        dup2(fd,0);
        dup2(fd,1);
        dup2(fd,2);
        close(fd);
    }
    

};